QuickTime 2.5 contained new support for developers of codecs to accelerate certain image decompression operations. These features will most likely be used by developers of video hardware boards that provide special acceleration features, such as arbitrary scaling or color space conversion.
Prior to QuickTime 2.5, if a codec could not decompress an image directly to the screen, the ICM would prepare an offscreen buffer for the codec, then use the None codec to transfer the image from the offscreen buffer to the screen. With QuickTime 2.5, if a codec cannot decompress directly to the screen it has the option of specifying that it can decompress to one or more types of non-RGB pixel spaces, specified as an OSType (e.g., 'yuvs' ). The ICM then attempts to find a decompressor component of that type (a transfer codec) that can transfer the image to the screen. Since the ICM does not define non-RGB pixel types, the transfer codec must support additional calls to set up the offscreen. If a transfer codec cannot be found that supports the specified non-RGB pixel types, the ICM uses the None codec with an RGB offscreen buffer.
The real speed benefit comes from the fact that since the transfer codec defines the offscreen buffer, it can place the buffer in on-board memory, or even point to an overlay plane so that the offscreen image really is on the screen. In this case, the additional step of transferring the bits from offscreen memory on to the screen is avoided.
For an image decompressor component to indicate that it can decompress to non-RGB pixel types, it should, in the ImageCodecPreDecompress call, fill in the wantedDestinationPixelTypes field with a handle to a zero-terminated list of pixel types that it can decompress to. The ICM immediately makes a copy of the handle. Cinepak, for example, returns a 12-byte handle containing yuvs , yuvu , and $00000000. Since ImageCodecPreDecompress can be called often, it is suggested that codecs allocate this handle when their component is opened and simply fill in the wantedDestinationPixelTypes field with this handle during ImageCodecPreDecompress . Components that use this method should be sure to dispose the handle at close.
Apple's Cinepak decompressor supports decompressing to 'yuvs' and 'yuvu' pixel types. Type 'yuvs' is a YUV format with u and v components signed (center point at $00), while 'yuvu' has the u and v component centered at $80. The YUV format used by QuickTime is described in "YUV" (page 1108) .
As an example, suppose XYZ Co. had a video board that had a YUV overlay plane capable of doing arbitrary scaling. The overlay plane takes data in the same format as Cinepak's 'yuvs' format. In this case, XYZ would make a component of type 'imdc' and subtype 'yuvs' .
The ImageCodecPreDecompress call would set the codecCanScale , codecHasVolatileBuffe r, and codecImageBufferIsOnScreen bits in the capabilities->flags field. The codecImageBufferIsOnScreen bit is necessary to inform the ICM that the codec is a direct screen transfer codec. A direct screen transfer codec is one that sets up an offscreen buffer that is actually onscreen (such as an overlay plane). Not setting this bit correctly can cause unpredictable results.
The real work of the codec takes place in the ImageCodecNewImageBufferMemory call. This is where the codec is instructed to prepare the non-RGB pixel buffer. The codec must fill in the baseAddr and rowBytes fields of the dstPixMa p structure in the CodecDecompressParams . The ICM then passes these values to the original codec (e.g., Cinepak) to decompress into.
The codec must also implement ImageCodecDisposeMemory to balance ImageCodecNewImageBufferMemory .
Since Cinepak then decompresses into the card's overlay plane, ImageCodecBandDecompress needs to do nothing aside from calling ICMDecompressComplete .
pascal ComponentResult
ImageCodecPreDecompress(Handle storage,
CodecDecompressParams *p)
{
CodecCapabilities *capabilities = p->capabilities;
// only allow 16 bpp source
if ((**p->imageDescription).depth != 16)
return codecConditionErr;
/* we only support 16 bits per pixel dest */
if (p->dstPixMap.pixelSize != 16)
return codecConditionErr;
capabilities->wantedPixelSize = p->dstPixMap.pixelSize;
capabilities->bandInc = capabilities->bandMin =
(*p->imageDescription)->height;
capabilities->extendWidth = 0;
capabilities->extendHeight = 0;
capabilities->flags =
codecCanScale | codecImageBufferIsOnScreen |
codecHasVolatileBuffer;
return noErr;
}
pascal ComponentResult
ImageCodecBandDecompress(Handle storage,
CodecDecompressParams *p)
{
ICMDecompressComplete(p->sequenceID, noErr,
codecCompletionSource | codecCompletionDest,
&p->completionProcRecord);
return noErr;
}
pascal ComponentResult
ImageCodecNewImageBufferMemory(Handle storage,
CodecDecompressParams *p, long flags,
ICMMemoryDisposedUPP memoryGoneProc,
void *refCon)
{
OSErr err = noErr;
long offsetH, offsetV;
Ptr baseAddr;
long rowBytes;
// call predecompress to check to make sure we can handle
// this destination
err = ImageCodecPreDecompress(storage, p);
if (err) goto bail;
// set video board registers with the scale
XYZVideoSetScale(p->matrix);
// calculate a base address to write to
offsetH = (p->dstRect.left - p->dstPixMap.bounds.left);
offsetV = (p->dstRect.top - p->dstPixMap.bounds.top);
XYZVideoGetBaseAddress(p->dstPixMap, offsetH, offsetV,
&baseAddr, &rowBytes);
p->dstPixMap.baseAddr = baseAddr;
p->dstPixMap.rowBytes = rowBytes;
p->capabilities->flags = codecImageBufferIsOnScreen;
bail:
return err;
}
pascal ComponentResult
ImageCodecDisposeMemory(Handle storage, Ptr data)
{
return noErr;
}
Some video hardware boards that use an overlay plane require that the image area on screen be flooded with a particular RGB value or alpha-channel in order to have the overlay buffer "show through" at that location. Codecs that require this support should set the screenFloodMethod and screenFloodValue fields of the CodecDecompressParams record during ImageCodecPreDecompress . The ICM then manages the flooding of the screen buffer. This method is more reliable than having the codec attempt to flood the screen itself, and will ensure compatibility with future versions of QuickTime.
| Previous | Chapter Contents | Chapter Top | Next |